package 多线程;

import java.util.concurrent.CountDownLatch;
import java.util.concurrent.Semaphore;

/**
 我们提供了一个类：

 public class Foo {
   public void first() { print("first"); }
   public void second() { print("second"); }
   public void third() { print("third"); }
 }
 三个不同的线程将会共用一个 Foo 实例。

 线程 A 将会调用 first() 方法
 线程 B 将会调用 second() 方法
 线程 C 将会调用 third() 方法
 请设计修改程序，以确保 second() 方法在 first() 方法之后被执行，third() 方法在 second() 方法之后被执行。

 示例 1:
 输入: [1,2,3]
 输出: "firstsecondthird"
 解释:
 有三个线程会被异步启动。
 输入 [1,2,3] 表示线程 A 将会调用 first() 方法，线程 B 将会调用 second() 方法，线程 C 将会调用 third() 方法。
 正确的输出是 "firstsecondthird"。
 示例 2:
 输入: [1,3,2]
 输出: "firstsecondthird"
 解释:
 输入 [1,3,2] 表示线程 A 将会调用 first() 方法，线程 B 将会调用 third() 方法，线程 C 将会调用 second() 方法。
 正确的输出是 "firstsecondthird"

 */

public class _1114按序打印 {
    public _1114按序打印() {

    }
    // 基于信号量开发
    public Semaphore s1=  new Semaphore(0);
    public Semaphore s2=  new Semaphore(0);
    public void first(Runnable printFirst) throws InterruptedException {

        // printFirst.run() outputs "first". Do not change or remove this line.
        printFirst.run();
        s1.release();
    }

    public void second(Runnable printSecond) throws InterruptedException {
        s1.acquire();
        // printSecond.run() outputs "second". Do not change or remove this line.
        printSecond.run();
        s2.release();
    }

    public void third(Runnable printThird) throws InterruptedException {
        s2.acquire();
        // printThird.run() outputs "third". Do not change or remove this line.
        printThird.run();
    }
    // 基于 CountDownLatch

    public CountDownLatch cdl1 = new CountDownLatch(1);
    public CountDownLatch cdl2 = new CountDownLatch(1);
    public void first2(Runnable printFirst) throws InterruptedException {
        // printFirst.run() outputs "first". Do not change or remove this line.
        printFirst.run();
        cdl1.countDown();
    }

    public void second2(Runnable printSecond) throws InterruptedException {
        cdl1.await();
        // printSecond.run() outputs "second". Do not change or remove this line.
        printSecond.run();
        cdl2.countDown();
    }

    public void third2(Runnable printThird) throws InterruptedException {
        cdl2.await();
        // printThird.run() outputs "third". Do not change or remove this line.
        printThird.run();
    }


}
